package com.leador.batch;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.leador.assist.DataQueueManager;
import com.leador.batch.db.DatabaseManager;
import com.leador.core.KernelThread;
import com.leador.http.HttpManager;
import com.leador.jni.TraceJniInterface;
import com.leador.listener.OnPointListener;
import com.leador.module.AppInfo;
import com.leador.module.ILocation;
import com.leador.module.response.Result;
import com.leador.service.LBSTraceService;
import com.leador.utils.Utils;

/**
 * Created by liuha on 2016/9/17.
 */
public class BatchReportManager implements OnPointListener{
    private static BatchReportManager INSTANCE;
    private LBSTraceService lbsTraceService;
    private KernelThread kernelThread;
    private  SyncHttpThread syncHttpThread;
    private static ILocation iLocation;
    private ILocation oldLocation = null;
    private BatchReportManager(LBSTraceService lbsTraceService,KernelThread kernelThread){
        this.lbsTraceService = lbsTraceService;
        this.kernelThread = kernelThread;
    }
    public static BatchReportManager getInstance(LBSTraceService lbsTraceService,KernelThread kernelThread){
        if(INSTANCE == null){
            synchronized (BatchReportManager.class){
                if(INSTANCE == null){
                    INSTANCE = new BatchReportManager(lbsTraceService,kernelThread);
                }
            }
        }
        return INSTANCE;
    }

    public void batch(){
        //提示进入缓存
        Handler handler = lbsTraceService.getLbsServiceHandler();
        boolean hasNetWork = Utils.isNetworkConnected(lbsTraceService.getContext());
        if(!hasNetWork){
            handler.sendEmptyMessage(31);
        }else{
            handler.sendEmptyMessage(32);
        }

        //开线程去同步
        syncHttpThread = new SyncHttpThread(lbsTraceService,this);
        syncHttpThread.start();

        //设置Location 并且提交
        setILocation();
    }

    public void setILocation(){
        byte[] bt = TraceJniInterface.buildLocData(lbsTraceService.getContext());
        if(bt == null ){
            return;
        }

        String btStr = new String(bt);
        if(btStr.equals("")){
            return;
        }
        Log.e("btStr is",btStr);
        iLocation = ILocation.jsonToBean(btStr);
        if(iLocation == null){
            return;
        }
        iLocation.setAk(AppInfo.key);
        iLocation.setEntity_name(AppInfo.entityName);
        iLocation.setService_id(String.valueOf(AppInfo.serviceId));
        iLocation.setCoord_type("2");
        //判断是否符合上报条件
        boolean isNeedReport = isNeedReport();
        if(!isNeedReport){
            return;
        }
        //设置最新的位置
        oldLocation = iLocation;
//        //缓存状态
        if(kernelThread.isCache){
            insertDBLocation(lbsTraceService.getContext());
            return;
        }
       //提交
        postSubmit();
    }

    /**
     * 入库
     */
    public static void insertDBLocation(Context context){
        if(iLocation == null){
            return;
        }
        //入库
        DatabaseManager.getInstance(context).insert(iLocation);
    }

    public static void insertDBLocations(Context context){
        //批量入库
        DatabaseManager.getInstance(context).inserts();

    }

    /**
     * 提交
     */
    public void postSubmit(){
        HttpManager.getInstance().addTrack(lbsTraceService.getContext(),iLocation,this);
    }

    @Override
    public void apointSucess(Result result) {
        Log.e("单点上报成功 is",result.toString());
        if(!result.getStatus().equals("0")){
            insertDBLocation(lbsTraceService.getContext());
        }
    }

    @Override
    public void apontOnFailure(Result result) {
        Log.e("单点上报失败 is",result.toString());
        insertDBLocation(lbsTraceService.getContext());
    }

    @Override
    public void apointsSucess(Result result) {
        Log.e("多点上报成功 is",result.toString());
        if(result.getStatus().equals("0")) {
            DataQueueManager.getInstance().clearILocation();
        }else{
            //失败入库
            insertDBLocations(lbsTraceService.getContext());
        }
    }

    @Override
    public void apontsOnFailure(Result result) {
        Log.e("多点上报失败",result.toString());
        insertDBLocations(lbsTraceService.getContext());
    }

    /**
     * 判断是否新位置
     * @return true 是 ，false 否
     */
    public boolean isNeedReport(){
        if(oldLocation == null){
            return true;
        }
        return isNeedUpdate(oldLocation,iLocation);
    }

    /**
     * 是否需要上报
     * @param oldLoc
     * @param newLoc
     * @return
     */
    private boolean isNeedUpdate(ILocation oldLoc, ILocation newLoc){
        if(oldLoc.getLatitude()==null||oldLoc.getLongitude()==null){
            return true;
        }

        if(newLoc.getLatitude()==null||newLoc.getLongitude()==null){
            return true;
        }

        //距离判断
        if(lbsTraceService.getLocateHelper().distanceInterval>0){
            double len = getDistance(Double.parseDouble(oldLoc.getLongitude()),Double.parseDouble(oldLoc.getLatitude()),
                    Double.parseDouble(newLoc.getLongitude()) ,Double.parseDouble(newLoc.getLatitude()));
            if(len<lbsTraceService.getLocateHelper().distanceInterval){
                return false;
            }
        }
        return true;
    }

    /**
     * 获取两点间距离
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    private double getDistance(double x1, double y1, double x2, double y2) {
        double latRadians1 = y1 * (Math.PI / 180);
        double latRadians2 = y2 * (Math.PI / 180);
        double latRadians = latRadians1 - latRadians2;
        double lngRadians = x1 * (Math.PI / 180) - x2 * (Math.PI / 180);
        double f = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(latRadians / 2), 2) + Math.cos(latRadians1) * Math.cos(latRadians2) * Math.pow(Math.sin(lngRadians / 2), 2)));
        return f * 6378137;
    }

}
